// import {} from 'es-toolkit';
/**** copy form es-toolkit */
/**
 * @type {import('es-toolkit').debounce}
 */
function debounce(func, debounceMs, { signal, edges } = {}) {
  let pendingThis = undefined;
  let pendingArgs = null;
  const leading = edges != null && edges.includes('leading');
  const trailing = edges == null || edges.includes('trailing');
  const invoke = () => {
      if (pendingArgs !== null) {
          func.apply(pendingThis, pendingArgs);
          pendingThis = undefined;
          pendingArgs = null;
      }
  };
  const onTimerEnd = () => {
      if (trailing) {
          invoke();
      }
      cancel();
  };
  let timeoutId = null;
  const schedule = () => {
      if (timeoutId != null) {
          clearTimeout(timeoutId);
      }
      timeoutId = setTimeout(() => {
          timeoutId = null;
          onTimerEnd();
      }, debounceMs);
  };
  const cancelTimer = () => {
      if (timeoutId !== null) {
          clearTimeout(timeoutId);
          timeoutId = null;
      }
  };
  const cancel = () => {
      cancelTimer();
      pendingThis = undefined;
      pendingArgs = null;
  };
  const flush = () => {
      cancelTimer();
      invoke();
  };
  const debounced = function (...args) {
      if (signal?.aborted) {
          return;
      }
      pendingThis = this;
      pendingArgs = args;
      const isFirstCall = timeoutId == null;
      schedule();
      if (leading && isFirstCall) {
          invoke();
      }
  };
  debounced.schedule = schedule;
  debounced.cancel = cancel;
  debounced.flush = flush;
  signal?.addEventListener('abort', cancel, { once: true });
  return debounced;
}

/**
 * @type {import('es-toolkit').throttle}
 */

function throttle(func, throttleMs, { signal, edges = ['leading', 'trailing'] } = {}) {
    let pendingAt = null;
    const debounced = debounce(func, throttleMs, { signal, edges });
    const throttled = function (...args) {
        if (pendingAt == null) {
            pendingAt = Date.now();
        }
        else {
            if (Date.now() - pendingAt >= throttleMs) {
                pendingAt = Date.now();
                debounced.cancel();
                debounced(...args);
            }
        }
        debounced(...args);
    };
    throttled.cancel = debounced.cancel;
    throttled.flush = debounced.flush;
    return throttled;
}

/*****/
const MutationObserver =
  window.MutationObserver ||
  window.WebKitMutationObserver ||
  window.MozMutationObserver;
// target
const list = document.querySelector(`ol`);
// options
const config = {
  attributes: true,
  childList: true,
  characterData: true,
  subtree: true,
};
// instance
const observer = new MutationObserver(
  (function (mutations) {
    console.log(`mutations =`, mutations); // MutationRecord
    mutations.forEach(function (mutation) {
      console.log("mutation = ", mutation);
      if (mutation.type === "characterData") {
        // target & object === typeof(mutation.target)
        console.log("A child node has been added OR removed.", mutation.target, typeof(mutation.target));
        console.log("[...mutation.addedNodes].length", [...mutation.addedNodes].length);
        console.log("[...mutation.removedNodes].length", [...mutation.removedNodes].length);
        if (mutation.target && [...mutation.addedNodes].length) {
            // [...mutation.addedNodes].length
            console.log(`A child node ${mutation.target} has been added!`, mutation.target);
        }
        if (mutation.target && [...mutation.removedNodes].length) {
            // [...mutation.removedNodes].length
            console.log(`A child node ${mutation.target} has been removed!`, mutation.target);
        }
      }
      if (mutation.type === "childList") {
        if (mutation.target && [...mutation.addedNodes].length) {
          console.log(
            `A child node ${mutation.target} has been added!`,
            mutation.target,
          );
        }
        if (mutation.target && [...mutation.removedNodes].length) {
          console.log(
            `A child node ${mutation.target} has been removed!`,
            mutation.target,
          );
        }
        // do somwthings
        let list_values = [];
        list_values = Array.slice
          .call(list.children)
          .map(function (node) {
            return node.innerHTML;
          })
          .filter(function (str) {
            if (str === "<br>") {
              return false;
            } else {
              return true;
            }
          });
        console.log(list_values);
      }
      if (mutation.type === "attributes") {
        console.log("mutation =", mutation);
        console.log(
          `The \`${mutation.attributeName}\` attribute was modified.`,
        );
        console.log("list style =", list.style);
        let { width, height } = list.style;
        let style = {
          width,
          height,
        };
        console.log("style =\n", JSON.stringify(style, null, 4));
      }
    });
  }),
);
observer.observe(list, config);
// Later, you can stop observing
// setTimeout(() => {
//     observer.disconnect();
// }, 1000 * 100);
// bug ??? after disconnect
// list.attributes;
// list.setAttribute(`style`, `height: 212px; width: 213px;`);
// list.setAttribute(`data-test`, `666`);
// list.removeAttribute(`data-test`);
// list.children;
// list.childElementCount;
// list.childNodes;
// list.hasChildNodes();
// list.firstElementChild;
// list.firstChild;
// list.removeChild(li);
// list.removeChild(list.firstElementChild);
// list.replaceChild(li, li);
// list.replaceChild(list.firstElementChild, list.lastElementChild);
